<?php

namespace app\api\controller\wechat;

use app\common\controller\Api;
use fast\Http;
use fast\Random;
use app\common\model\User;
use app\common\library\Token;
use think\Config;
use think\Validate;
use think\Db;
use think\Cache;

use app\admin\model\Exam as ExamModel;

/**
 * 小程序 考试
 */
class Exam extends Api
{
    protected $noNeedLogin = [];
    protected $noNeedRight = ['*'];

    /**
     * 获取配置信息
     *
     * @return void
     */
    public function getConfig()
    {
        $site = Config::get('site');
        $this->success('', [
            "notice" => $site['notice'],
            "showanswer" => $site['showanswer'],
            "showanalysis" => $site['showanalysis'],
            "shownamegender" => $site['shownamegender'],
            "prevent" => $site['prevent'],
            "limits" => $site['limits'],
        ]);
    }

    /**
     * 考试列表
     *
     * @return void
     */
    public function getExamList()
    {
        $course_id = input('course_id');
        $limit = input('limit/d', 5);
        $model = new ExamModel;

        $list = $model->with('course')->where('status', 3)->order("starttime desc");
        // ->whereTime('starttime', '>=', 'today')
        if (isset($course_id)) {
            $list->where('course_id', $course_id);
        }
        $list = $list->paginate($limit)->each(function($item,$key){
            // 本场考试是否已考过
            $recorded = Db::name('record')->where('exam_id',$item->id)->where('user_id',$this->auth->id)->count();
            if($recorded){
                $item->hasRecord = $recorded;
            }
            else{
                $item->hasRecord = 0;
            }
        });

        foreach ($list as $k => $row) {
            // 考试名称 课程 试卷id 开始时间 结束时间 考试时长
            $row->visible(['title', 'id', 'course', 'testpaper_id', 'starttime', 'endtime', 'minutes','hasRecord']);
            $row->getRelation('course')->visible(['name', 'id']);
        }

        $this->success('ok', $list);
    }

    /**
     * 根据试卷id获取题目内容
     *
     * @param [type] $testpaper_id
     * @return void
     */
    public function getTestpaper($testpaper_id = null)
    {
        if (!isset($testpaper_id)) {
            $this->error('缺少试卷id');
        }

        $questions = Db::name('testpaper')->where('id', $testpaper_id)->value('questions');
        $questions = json_decode($questions, true);
        // var_dump($questions);exit;
        $qsArr = [];
        foreach ($questions as $type => $question) {

            $ids = array_column($question, 'id');
            

            if($type == 'type4'){
                $qs = DB::name('questions')->whereIn('id', $ids)->field('id,title,optionjson,diffdata,answers')->select();
                foreach ($qs as &$value) {
                    $answers = json_decode($value["answers"],true);
                    $value["answersCount"] = count($answers);
                    unset($value["answers"]);
                }
            }
            else{
                $qs = DB::name('questions')->whereIn('id', $ids)->field('id,title,optionjson,diffdata')->select();
            }

            $qsArr[$type] = $qs;
        }
        $this->success('', $qsArr);
    }

    /**
     * 提交考试
     */
    public function setRecord()
    {
        $rules = [
            'testpaper_id' => 'require',
            'exam_id' => 'require',
            'answers' => 'require',
            'starttime' => 'require|dateFormat:Y-m-d H:i:s',
        ];
        $validate = new Validate($rules);
        if (!$validate->check(input('post.'))) {
            $this->error($validate->getError());
        }

        $user_id = $this->auth->id;
        $testpaper_id = input('testpaper_id');
        $exam_id = input('exam_id');
        $answers = input('answers/a');
   
        $endtime = date('Y-m-d H:i:s');

        if (!Db::name('exam')->where('id', $exam_id)->where('testpaper_id', $testpaper_id)->find()) {
            $this->error('考试试卷不存在');
        }
        $model = new \app\admin\model\Record;

        // if($model->where('user_id',$user_id)->where('exam_id',$exam_id)->find()){
        //     $this->error('您已参加过考试');
        // }

        $starttime = Cache::get("examstart_".$user_id);
        if(!$starttime){
            $starttime = input('starttime');
        }
        else{
            $starttime = date("Y-m-d H:i:s",$starttime);
        }
        $seconds = strtotime($endtime) - strtotime($starttime);
        $minutes = ceil($seconds / 60);
        Db::startTrans();
        $result = false;
        try {
            
            $res = $model->save([
                'user_id' => $user_id,
                'exam_id' => $exam_id,
                'testpaper_id' => $testpaper_id,
                'starttime' => $starttime,
                'endtime' => $endtime,
                'minutes' => $minutes,
            ]);
    
            $record_id = $model->id;
    
            $questions = Db::name('testpaper')->where('id', $testpaper_id)->value('questions');
            $questions = json_decode($questions, true);
    
            $saveAnswerDatas = [];
            $score = 0;
            $hasType5 = false;
            foreach ($questions as $type => $question) {
                if(!empty($question)){
                    // 存在这个类型的题目 例如问答题
                    if($type == 'type5'){
                        $hasType5 = true;
                    }
    
                    $ids = array_column($question,'id');
                    $rightAnswers = Db::name('questions')->whereIn('id',$ids)->column('answers','id');
    
                    
                    foreach ($question as $k => $q) {
                        $id = $q["id"];
                        $grade = $q["grade"];
    
                        $saveAnswerArr = [
                            "record_id"=>$record_id,
                            "question_id"=>$id,
                            "answer_right"=>$rightAnswers[$id],
                            "answer_mine"=>"",
                            "grade"=>0,
                        ];
    
                        if(isset($answers[$id]) && !empty($answers[$id])){
                            $saveAnswerArr["answer_mine"] = json_encode($answers[$id],JSON_UNESCAPED_UNICODE);
                            // 问答题
                            if($type != 'type5'){
                                if($answers[$id] == json_decode($rightAnswers[$id],true)){
                                    // 回答正确
                                    $saveAnswerArr["grade"] = $grade;
    
                                    $score += $grade;
                                }
                            }
                        }
    
                        $saveAnswerDatas[] = $saveAnswerArr;
    
                        // $this->success('',$saveAnswerArr);
                    }
                }
            }
            Db::name('answers')->insertAll($saveAnswerDatas);
    
            if(!$hasType5){
                Db::name('record')->where('id',$record_id)->update([
                    "score"=>$score
                ]);
            }

            $result = true;

            Db::commit();

        } catch (\Throwable $th) {
            $result = false;
            Db::rollback();
            // throw $th;
            $errMsg = $th->getMessage();
        }
        

        if ($result) {
            // 成功后，返回具体的信息给前端，用于显示考试结果页面
            $this->success('成功',[
                "record_id"=>$record_id,
                "score"=>$score,
                "minutes"=>$minutes
            ]);
        }
        $this->error($errMsg ?? '失败');
    }

    /**
     * 开始考试
     *
     * @return void
     */
    public function startExam()
    {
        //   存储开始时间
        Cache::set('examstart_'.$this->auth->id,time());

        // 
        $this->success('ok',date('Y-m-d H:i:s'));
    }

    /**
     * 时间差验证
     *
     * @return void
     */
    public function checkTimeDiffer()
    {
      $timeDiffer = input('timeDiffer/d');
      if(!$timeDiffer){
        $this->error('请上传时间差');
      }

      $user_id = $this->auth->id;
      $start = Cache::get('examstart_'.$user_id);

      $differ = time() - $start;

      if(abs($timeDiffer - $differ) >60){
        $this->error('时间差不正确，有作弊嫌疑',[$timeDiffer,$differ,$start]);
      }

      $this->success('ok');
    }
    
    /**
     * 获取考试记录列表
     *
     * @return void
     */
    public function getRecordList()
    {
        $timeStart = input('timeStart');

        $scoreStart = input('scoreStart/d');
        $scoreEnd = input('scoreEnd/d');
        $model = new \app\admin\model\Record;
        $list = $model->with(['exam','testpaper'])->where('user_id',$this->auth->id);
        if($timeStart){
            $timeEnd = input('timeEnd',date('Y-m-d H:i:s'));
            $list->whereTime('record.starttime','between',[$timeStart,$timeEnd]);
        }

        if(isset($scoreStart) && isset($scoreEnd)){
            $list->where('record.score','between',[$scoreStart,$scoreEnd]);
        }

        $list = $list->order('record.starttime','desc')->paginate();

        foreach ($list as $key => $value) {
            $value->getRelation('exam')->visible(["title"]);
            $value->getRelation('testpaper')->visible(["grades"]);
        }
        $this->success('',$list);
    }

    /**
     * 根据记录id获取记录详情
     *
     * @param [type] $id
     * @return void
     */
    public function getRecordById($id = null)
    {
      if(!$id){
        $this->error('缺少id');
      }

      $data = Db::name('record')->where('id',$id)->find();

      if($data){
        $showanalysis = Config::get('site.showanalysis');
        $fields = 'a.*,q.title,q.typedata';
        if($showanalysis == '1'){
            $fields .= ',q.answerscontent';
        }
        $answers = Db::name('answers')->alias('a')
        ->join('questions q','a.question_id = q.id')
        ->where('record_id',$id)
        ->field($fields)
        ->select();

        $data["answers"] = $answers;
        $this->success('ok',$data);
      }
      else{
        $this->error('未找到考试记录');
      }
    }

    /**
     * 获取课程列表
     *
     * @return void
     */
    public function getCourse()
    {
      $list = Db::name('course')-> field(['name' => 'text', 'id' => 'value', 'pid' => 'pid']) ->order('id','asc')->select();
      $this->success('',$list);
    }
}
